'use strict';

const Service = require('./base');

const index = 'category';

class CategoryService extends Service {
  async selectOrder() {
    let result = [];
    try {
      const { hits: { hits } } = await this.app.elasticsearch.search({
        index,
        body: {
          sort: [
            { parent_id: { order: 'asc' } },
            { sort: { order: 'asc' } },
          ],
          from: 0,
          size: 100,
        },
      });
      result = hits;
    } catch (err) {
      this.error(err);
    }

    return result;
  }

  async getCategoryMap() {
    const categoryHits = await this.selectOrder();
    return categoryHits.reduce((total, item) => {
      const body = item._source;
      total[body.id] = body.text;
      return total;
    }, {});
  }

  /**
   * interfeace Props {
   *  id: string
   *  text: string
   *  sort: number
   *  parent_id: string
   * }
   * @param {Props[]} data 批量插入的数据
   *
   * interface Return {
   *  errors: Error[]
   *  count: number
   * }
   * @return {Return} 返回值
   */
  async bulkInsert(data) {
    const result = {
      errors: [],
      count: 0,
    };

    const body = data.flatMap(doc => [{ index: { _index: index } }, doc ]);
    const { errors, items } = await this.app.elasticsearch.bulk({ refresh: true, body });

    if (errors) {
      const erroredDocuments = [];
      items.forEach((action, i) => {
        const operation = Object.keys(action)[0];
        if (action[operation].error) {
          erroredDocuments.push({
            status: action[operation].status,
            error: action[operation].error,
            operation: body[i * 2],
            document: body[i * 2 + 1],
          });
        }
      });
      result.errors = erroredDocuments;
    }

    const { count } = await this.app.elasticsearch.count({ index });
    result.count = count;

    return result;
  }

  async deleteAll() {
    let result = true;
    try {
      await this.app.elasticsearch.deleteByQuery({
        index,
        refresh: true,
        body: {
          query: {
            match_all: {},
          },
        },
      });
    } catch (err) {
      result = false;
      this.error(err);
    }

    return result;
  }
}

module.exports = CategoryService;
